package com.market.web.model.report;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

import javax.faces.context.FacesContext;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.StreamedContent;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import com.market.domain.BaseObject;
import com.market.domain.Location;
import com.market.domain.Order;
import com.market.domain.OrderDetail;
import com.market.domain.Product;
import com.market.domain.transients.OrderQuery;
import com.market.domain.transients.ReportHeaderFooter;
import com.market.domain.transients.SalesGroupByProductQuery;
import com.market.domain.transients.SalesGroupByUserQuery;
import com.market.domain.transients.report.OrderDetailSummaryByProduct;
import com.market.domain.transients.report.SalesGroupByProduct;
import com.market.domain.transients.report.SalesGroupByUser;
import com.market.domain.transients.report.UserRecord;
import com.market.util.StringUtil;

@Component("reportModel")
@Scope("session")
public class ReportModel extends BaseObject {
	/**
	 * 
	 */
	private static final long serialVersionUID = -1817882539168764180L;

	protected final Log log = LogFactory.getLog(this.getClass());

	private Font tableHeaderFont;
	private Font tableContentFont;
	private ReportHeaderFooter reportHeaderFooter;
	private PdfWriter pdfWriter;
	private Document document;
	private ByteArrayOutputStream outputStream;

	private void init() {
		outputStream = null;
		try {
			BaseFont baseFont = BaseFont.createFont(FacesContext
					.getCurrentInstance().getExternalContext().getRealPath("")
					+ File.separator + "fonts" + File.separator + "SIMSUN.TTF",
					BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
			this.tableHeaderFont = new Font(baseFont, 10f,
					Font.FontStyle.BOLD.ordinal());
			tableContentFont = new Font(baseFont, 10f);

			outputStream = new ByteArrayOutputStream();
			document = new Document();
			pdfWriter = PdfWriter.getInstance(document, outputStream);
			Rectangle art = new Rectangle(36f, 18f, 559, 788);
			pdfWriter.setBoxSize("art", art);
			document.setPageSize(PageSize.A4);
			document.setMargins(36f, 36f, 108f, 18f);
			document.open();
			pdfWriter.setPageEvent(this.reportHeaderFooter);
		} catch (DocumentException e) {
			log.debug(e.toString());
			e.printStackTrace();
		} catch (IOException e) {
			log.debug(e.toString());
			e.printStackTrace();
		}

	}

	private void cleanUp() {
		this.tableHeaderFont = null;
		this.tableHeaderFont = null;
		try {
			document.close();
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

		document = null;
		try {
			pdfWriter.close();
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		pdfWriter = null;
		try {
			outputStream.close();
			outputStream = null;
		} catch (Exception e) {
			outputStream = null;
		}
	}

	public ReportHeaderFooter getReportHeaderFooter() {
		return reportHeaderFooter;
	}

	public void setReportHeaderFooter(ReportHeaderFooter reportHeaderFooter) {
		this.reportHeaderFooter = reportHeaderFooter;
	}

	// ***************************************

	private SalesGroupByProductQuery salesGroupByProductQuery = new SalesGroupByProductQuery();

	public SalesGroupByProductQuery getSalesGroupByProductQuery() {
		return salesGroupByProductQuery;
	}

	public void setSalesGroupByProductQuery(
			SalesGroupByProductQuery salesGroupByProductQuery) {
		this.salesGroupByProductQuery = salesGroupByProductQuery;
	}

	private List<SalesGroupByProduct> salesGroupByProduct;

	public List<SalesGroupByProduct> getSalesGroupByProduct() {
		return salesGroupByProduct;
	}

	public void setSalesGroupByProduct(
			List<SalesGroupByProduct> salesGroupByProduct) {
		this.salesGroupByProduct = salesGroupByProduct;
	}

	public Long getSalesGroupByProductOrderedTotalQuantity() {
		Long total = 0L;
		for (SalesGroupByProduct sales : this.salesGroupByProduct) {
			total = total + sales.getOrderedQuantity();
		}
		return total;
	}

	public Long getSalesGroupByProductDeliveredTotalQuantity() {
		Long total = 0L;
		for (SalesGroupByProduct sales : this.salesGroupByProduct) {
			total = total + sales.getDeliveredQuantity();
		}
		return total;
	}

	public String getSalesGroupByProductOrderedTotalAmountLabel() {
		Double total = 0D;
		for (SalesGroupByProduct sales : this.salesGroupByProduct) {
			total = total + sales.getOrderedAmount();
		}
		return super.formatDoubleToString(total);
	}

	public String getSalesGroupByProductDeliveredTotalAmountLabel() {
		Double total = 0D;
		for (SalesGroupByProduct sales : this.salesGroupByProduct) {
			total = total + sales.getDeliveredAmount();
		}
		return super.formatDoubleToString(total);
	}

	// ********************************************

	private SalesGroupByUserQuery salesGroupByUserQuery = new SalesGroupByUserQuery();

	public SalesGroupByUserQuery getSalesGroupByUserQuery() {
		return salesGroupByUserQuery;
	}

	public void setSalesGroupByUserQuery(
			SalesGroupByUserQuery salesGroupByUserQuery) {
		this.salesGroupByUserQuery = salesGroupByUserQuery;
	}

	private List<SalesGroupByUser> salesGroupByUser;

	public List<SalesGroupByUser> getSalesGroupByUser() {
		return salesGroupByUser;
	}

	public void setSalesGroupByUser(List<SalesGroupByUser> salesGroupByUser) {
		this.salesGroupByUser = salesGroupByUser;
	}

	public Double getSalesGroupByUserTotal() {
		Double salesTotal = 0D;
		for (SalesGroupByUser sales : this.salesGroupByUser) {
			salesTotal = salesTotal + sales.getSalesTotal();
		}
		return salesTotal;
	}

	public String getSalesGroupByUserTotalLabel() {
		Double salesTotal = this.getSalesGroupByUserTotal();
		return super.formatDoubleToString(salesTotal);
	}

	// *****************************************

	private OrderQuery orderQuery = new OrderQuery();

	public OrderQuery getOrderQuery() {
		return orderQuery;
	}

	public void setOrderQuery(OrderQuery orderQuery) {
		this.orderQuery = orderQuery;
	}

	private List<OrderDetailSummaryByProduct> orderDetailsSummaryByProducts;

	public List<OrderDetailSummaryByProduct> getOrderDetailsSummaryByProducts() {
		return orderDetailsSummaryByProducts;
	}

	public void setOrderDetailsSummaryByProducts(
			List<OrderDetailSummaryByProduct> orderDetailsSummaryByProducts) {
		this.orderDetailsSummaryByProducts = orderDetailsSummaryByProducts;
	}

	public Double getOrderDetailSummaryByProductOrderedTotal() {
		Double orderedTotal = 0D;
		for (OrderDetailSummaryByProduct detail : this.orderDetailsSummaryByProducts) {
			orderedTotal = detail.getOrderedSubtotal() + orderedTotal;
		}
		return orderedTotal;
	}

	public String getOrderDetailSummaryByProductOrderedTotalLabel() {
		Double orderedTotal = 0D;
		for (OrderDetailSummaryByProduct detail : this.orderDetailsSummaryByProducts) {
			orderedTotal = detail.getOrderedSubtotal() + orderedTotal;
		}
		return super.formatDoubleToString(orderedTotal);
	}

	public Double getOrderDetailsSummaryByProductConfirmedTotal() {
		Double total = 0D;
		for (OrderDetailSummaryByProduct detail : this.orderDetailsSummaryByProducts) {
			total = detail.getConfirmedSubtotal() + total;
		}

		return total;
	}

	public String getOrderDetailSummaryByProductConfirmedTotalLabel() {
		Double total = this.getOrderDetailsSummaryByProductConfirmedTotal();

		return super.formatDoubleToString(total);
	}

	public Double getOrderDetailSummaryByProductDeliveredTotal() {
		Double total = 0D;
		for (OrderDetailSummaryByProduct detail : this.orderDetailsSummaryByProducts) {
			total = detail.getDeliveredSubtotal() + total;
		}

		return total;
	}

	public String getOrderDetailSummaryByProductDeliveredTotalLabel() {
		Double total = this.getOrderDetailSummaryByProductDeliveredTotal();

		return super.formatDoubleToString(total);
	}

	public StreamedContent printProduct(List<Product> products) {
		try {
			this.init();
			PdfPTable pdfTable = new PdfPTable(8);
			pdfTable.setWidthPercentage(100f);
			pdfTable.addCell(new Phrase("Number", this.tableHeaderFont));
			pdfTable.addCell(new Phrase("Name", this.tableHeaderFont));
			pdfTable.addCell(new Phrase("Inventory", this.tableHeaderFont));
			pdfTable.addCell(new Phrase("Spec. Desc.", this.tableHeaderFont));
			pdfTable.addCell(new Phrase("Price Unit", this.tableHeaderFont));
			pdfTable.addCell(new Phrase("Price", this.tableHeaderFont));
			pdfTable.addCell(new Phrase("Special price", this.tableHeaderFont));
			pdfTable.addCell(new Phrase("Memo", this.tableHeaderFont));
			pdfTable.setHeaderRows(1);
			for (Product product : products) {

				pdfTable.addCell(new Phrase(product.getNumber(),
						this.tableContentFont));
				if (product.getChineseName() != null
						&& !product.getChineseName().isEmpty()) {
					pdfTable.addCell(new Phrase(product.getChineseName(),
							this.tableContentFont));
				} else {
					pdfTable.addCell(new Phrase(product.getName(),
							this.tableContentFont));
				}
				pdfTable.addCell(new Phrase(product.getInventory().toString(),
						this.tableContentFont));
				pdfTable.addCell(new Phrase(product.getSpecificationDesc(),
						this.tableContentFont));
				pdfTable.addCell(new Phrase(product.getPriceUnit(),
						this.tableContentFont));
				pdfTable.addCell(new Phrase(product.getPrice().toString(),
						this.tableContentFont));
				pdfTable.addCell(new Phrase(product.getSpecialPrice()
						.toString(), this.tableContentFont));
				pdfTable.addCell(new Phrase("  ", this.tableContentFont));

			}
			float[] columnsWidths = { 40f, 130f, 50f, 100f, 40f, 40f, 40f, 80f };
			pdfTable.setWidths(columnsWidths);
			document.add(pdfTable);
			document.close();
			InputStream input = new ByteArrayInputStream(
					outputStream.toByteArray());
			StreamedContent content = new DefaultStreamedContent(input, "pdf",
					"productList.pdf");
			return content;
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			this.cleanUp();
		}
		return null;
	}

	/**
	 * Use this report to take-out products from fridge or warehouse, So we can prepare orders. 
	 * @return
	 */
	
	public StreamedContent getOrderPrepareSummaryPdf() {
		try {
			this.init();
			PdfPTable pdfTable = new PdfPTable(10);
			pdfTable.setWidthPercentage(100f);
			pdfTable.addCell(new Phrase("No.", this.tableHeaderFont));
			pdfTable.addCell(new Phrase("ID", this.tableHeaderFont));
			pdfTable.addCell(new Phrase("Location", this.tableHeaderFont));
			pdfTable.addCell(new Phrase("Number", this.tableHeaderFont));
			pdfTable.addCell(new Phrase("Name", this.tableHeaderFont));
			pdfTable.addCell(new Phrase("WS Inv.", this.tableHeaderFont));
			pdfTable.addCell(new Phrase("Conf. QTY", this.tableHeaderFont));
			pdfTable.addCell(new Phrase("QTY in ST", this.tableHeaderFont));
			pdfTable.addCell(new Phrase("Price Unit", this.tableHeaderFont));
			pdfTable.addCell(new Phrase("Spec. Desc.", this.tableHeaderFont));
			pdfTable.setHeaderRows(1);
			Integer i = 0;
			for (OrderDetailSummaryByProduct detail : this.orderDetailsSummaryByProducts) {
				i++;
				pdfTable.addCell(new Phrase(i.toString(), this.tableContentFont));
				pdfTable.addCell(new Phrase(detail.getId().toString(),
						this.tableContentFont));
				pdfTable.addCell(new Phrase(detail.getStorageLocation(),
						this.tableContentFont));
				pdfTable.addCell(new Phrase(detail.getNumber(),
						this.tableContentFont));
				pdfTable.addCell(new Phrase(detail.getChineseName(),
						this.tableContentFont));
				pdfTable.addCell(new Phrase(detail.getInventory().toString(),
						this.tableContentFont));
				pdfTable.addCell(new Phrase(detail.getConfirmedQuantity()
						.toString(), this.tableContentFont));
				pdfTable.addCell(new Phrase(String.valueOf(detail
						.getInventory() + detail.getConfirmedQuantity()),
						this.tableContentFont));
				pdfTable.addCell(new Phrase(detail.getUnit() + "/"
						+ detail.getChineseUnit() + "/"
						+ detail.getFrenchUnit(), this.tableContentFont));
				pdfTable.addCell(new Phrase(detail.getSpecDesc(),
						this.tableContentFont));
			}
			float[] columnsWidths = { 20f, 20f, 90f, 40f, 100f, 30f, 30f, 30f,
					80f, 80f };
			pdfTable.setWidths(columnsWidths);
			document.add(pdfTable);
			document.close();
			InputStream input = new ByteArrayInputStream(
					outputStream.toByteArray());
			StreamedContent content = new DefaultStreamedContent(input, "pdf",
					"prepareSummary.pdf");
			return content;
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			this.cleanUp();
		}
		return null;
	}
	
	
	/**
	 * Use this report to do the purchasing, purchase quantity is based on ordered 
	 * quantity, Use this report the day before we prepare order.
	 * @return
	 */
	public StreamedContent getOrderPurchaseSummaryPdf() {
		try {
			this.init();
			PdfPTable pdfTable = new PdfPTable(8);
			pdfTable.setWidthPercentage(100f);
			pdfTable.addCell(new Phrase("No.", this.tableHeaderFont));
			pdfTable.addCell(new Phrase("ID", this.tableHeaderFont));
			pdfTable.addCell(new Phrase("Number", this.tableHeaderFont));
			pdfTable.addCell(new Phrase("Name", this.tableHeaderFont));
			pdfTable.addCell(new Phrase("WS Inv.", this.tableHeaderFont));
			pdfTable.addCell(new Phrase("Ordered QTY", this.tableHeaderFont));
			pdfTable.addCell(new Phrase("Price Unit", this.tableHeaderFont));
			pdfTable.addCell(new Phrase("Spec. Desc.", this.tableHeaderFont));
			pdfTable.setHeaderRows(1);
			Integer i = 0;
			for (OrderDetailSummaryByProduct detail : this.orderDetailsSummaryByProducts) {
				i++;
				pdfTable.addCell(new Phrase(i.toString(), this.tableContentFont));
				pdfTable.addCell(new Phrase(detail.getId().toString(),
						this.tableContentFont));
				pdfTable.addCell(new Phrase(detail.getNumber(),
						this.tableContentFont));
				pdfTable.addCell(new Phrase(detail.getChineseName(),
						this.tableContentFont));
				pdfTable.addCell(new Phrase(detail.getInventory().toString(),
						this.tableContentFont));
				pdfTable.addCell(new Phrase(detail.getOrderedQuantity().toString(), this.tableContentFont));
				pdfTable.addCell(new Phrase(detail.getUnit() + "/"
						+ detail.getChineseUnit() + "/"
						+ detail.getFrenchUnit(), this.tableContentFont));
				pdfTable.addCell(new Phrase(detail.getSpecDesc(),
						this.tableContentFont));
			}
			float[] columnsWidths = { 20f, 40f, 80f, 110f,50f, 50f, 85f, 85f};
			pdfTable.setWidths(columnsWidths);
			document.add(pdfTable);
			document.close();
			InputStream input = new ByteArrayInputStream(
					outputStream.toByteArray());
			StreamedContent content = new DefaultStreamedContent(input, "pdf",
					"purchaseSummary.pdf");
			return content;
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			this.cleanUp();
		}
		return null;
	}


	private List<Order> orderList;

	public List<Order> getOrderList() {
		return orderList;
	}

	public void setOrderList(List<Order> orderList) {
		this.orderList = orderList;
	}

	/**
	 * Use this report when deliver order.
	 * 
	 * @return
	 */

	public StreamedContent getOrderListPdf() {

		try {
			this.init();
			PdfPTable pdfTable = new PdfPTable(9);
			pdfTable.setWidthPercentage(100f);
			pdfTable.addCell(new Phrase("No.", this.tableHeaderFont));
			pdfTable.addCell(new Phrase("Order No.", this.tableHeaderFont));
			pdfTable.addCell(new Phrase("Name", this.tableHeaderFont));
			// pdfTable.addCell(new Phrase("Address", this.tableHeaderFont));
			pdfTable.addCell(new Phrase("Telephone", this.tableHeaderFont));
			pdfTable.addCell(new Phrase("Sub-total", this.tableHeaderFont));
			pdfTable.addCell(new Phrase("GST", this.tableHeaderFont));
			pdfTable.addCell(new Phrase("QST", this.tableHeaderFont));
			pdfTable.addCell(new Phrase("Charge", this.tableHeaderFont));
			pdfTable.addCell(new Phrase("Memo", this.tableHeaderFont));
			PdfPCell totalCell = new PdfPCell(new Phrase("Total",
					this.tableHeaderFont));
			totalCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
			totalCell.setColspan(4);
			pdfTable.addCell(totalCell);
			DecimalFormat df = new DecimalFormat("#.00");
			Double subTotalTotal = 0D;
			Double GSTTotal = 0D;
			Double QSTTotal = 0D;
			Double chargeTotal = 0D;
			for (Order order : this.orderList) {
				subTotalTotal = subTotalTotal
						+ order.getDeliveredTotalChargeExcludeTax();
				GSTTotal = GSTTotal + order.getDeliveredTotalGST();
				QSTTotal = QSTTotal + order.getDeliveredTotalQST();
				chargeTotal = chargeTotal + order.getDeliveredTotalCharge() ;
			}

			String subTotalTotalLabel = df.format(subTotalTotal);
			PdfPCell subTotalTotalLabelCell = new PdfPCell(new Phrase(
					subTotalTotalLabel, this.tableHeaderFont));
			subTotalTotalLabelCell.setColspan(1);
			subTotalTotalLabelCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
			pdfTable.addCell(subTotalTotalLabelCell);

			String GSTTotalLabel = df.format(GSTTotal);
			PdfPCell GSTTotalLabelCell = new PdfPCell(new Phrase(GSTTotalLabel,
					this.tableHeaderFont));
			GSTTotalLabelCell.setColspan(1);
			GSTTotalLabelCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
			pdfTable.addCell(GSTTotalLabelCell);

			String QSTTotalLabel = df.format(QSTTotal);
			PdfPCell QSTTotalLabelCell = new PdfPCell(new Phrase(QSTTotalLabel,
					this.tableHeaderFont));
			QSTTotalLabelCell.setColspan(1);
			QSTTotalLabelCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
			pdfTable.addCell(QSTTotalLabelCell);

			String chargeTotalLabel = df.format(chargeTotal);
			PdfPCell chargeTotalLabelCell = new PdfPCell(new Phrase(
					chargeTotalLabel, this.tableHeaderFont));
			chargeTotalLabelCell.setColspan(1);
			chargeTotalLabelCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
			pdfTable.addCell(chargeTotalLabelCell);

			Long chargeLocationTotal = new Double(((subTotalTotal * 0.95D
					+ GSTTotal + QSTTotal) * 100D)).longValue();
			String chargeLocationTotalLabel = String
					.valueOf(chargeLocationTotal);
			PdfPCell chargeLocationTotalLabelCell = new PdfPCell(new Phrase(chargeLocationTotalLabel,
					this.tableHeaderFont));
			chargeLocationTotalLabelCell.setColspan(1);
			chargeLocationTotalLabelCell
					.setHorizontalAlignment(Element.ALIGN_RIGHT);
			pdfTable.addCell(chargeLocationTotalLabelCell);

			pdfTable.setHeaderRows(2);
			pdfTable.setFooterRows(1);
			Integer i = 0;
			for (Order order : this.orderList) {
				i++;
				pdfTable.addCell(new Phrase(i.toString(), this.tableContentFont));
				pdfTable.addCell(new Phrase(order.getNumber(),
						this.tableContentFont));
				pdfTable.addCell(new Phrase(order.getCustomer().getLastName()
						+ " " + order.getCustomer().getFirstName(),
						this.tableContentFont));
				// pdfTable.addCell(new Phrase(order.getCustomer().getAddress(),
				// this.tableContentFont));
				pdfTable.addCell(new Phrase(order.getCustomer().getTelephone(),
						this.tableContentFont));

				PdfPCell subTotalCell = new PdfPCell(new Phrase(
						order.getDeliveredTotalChargeExcludeTaxLabel(),
						this.tableContentFont));
				subTotalCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
				pdfTable.addCell(subTotalCell);

				PdfPCell GSTCell = new PdfPCell(new Phrase(
						order.getDeliveredTotalGSTLabel(),
						this.tableContentFont));
				GSTCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
				pdfTable.addCell(GSTCell);

				PdfPCell QSTCell = new PdfPCell(new Phrase(
						order.getDeliveredTotalQSTLabel(),
						this.tableContentFont));
				QSTCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
				pdfTable.addCell(QSTCell);

				PdfPCell totalChargeCell = new PdfPCell(new Phrase(
						order.getDeliveredTotalChargeLabel(),
						this.tableContentFont));
				totalChargeCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
				pdfTable.addCell(totalChargeCell);

				// Memo Cell
				pdfTable.addCell(new Phrase("", this.tableContentFont));
			}
			float[] columnsWidths = { 20f, 80f, 90f, 80f, 55f, 35f, 35f, 50f,
					80f };
			pdfTable.setWidths(columnsWidths);
			document.add(pdfTable);
			document.close();
			InputStream input = new ByteArrayInputStream(
					outputStream.toByteArray());
			StreamedContent content;
			content = new DefaultStreamedContent(input, "pdf", "OrderList.pdf");
			return content;
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			this.cleanUp();
		}
		return null;
	}

	/**
	 * Use this method when customer want to see order's detail items.
	 * We normally send it to customer by email, do not print this report.
	 * @return
	 */
	public StreamedContent getOrderDetailListPdf() {

		try {
			this.init();
			PdfPTable pdfTable = new PdfPTable(8);
			pdfTable.setWidthPercentage(100f);
			pdfTable.addCell(new Phrase("No.", this.tableHeaderFont));
			pdfTable.addCell(new Phrase("Order No.", this.tableHeaderFont));
			pdfTable.addCell(new Phrase("Name", this.tableHeaderFont));
			pdfTable.addCell(new Phrase("Address", this.tableHeaderFont));
			pdfTable.addCell(new Phrase("Telephone", this.tableHeaderFont));
			PdfPCell detailCellHeader = new PdfPCell(new Phrase("Order Detail",
					this.tableHeaderFont));
			detailCellHeader.setColspan(4);
			pdfTable.addCell(detailCellHeader);
			// PdfPCell totalCell = new PdfPCell(new Phrase("Total",
			// this.tableHeaderFont));
			// totalCell.setColspan(5);
			// pdfTable.addCell(totalCell);
			DecimalFormat df = new DecimalFormat("#.00");
			// Double total = 0D;
			// for (Order order : this.orderList) {
			// total = total + order.getDeliveredTotalCharge();
			// }
			//
			// pdfTable.addCell(new Phrase(df.format(total),
			// this.tableHeaderFont));
			pdfTable.setHeaderRows(1);
			// pdfTable.setFooterRows(1);
			Integer i = 0;
			PdfPCell orderBlankCell = new PdfPCell(new Phrase("",
					this.tableContentFont));
			orderBlankCell.setColspan(3);
			PdfPCell detailBlankCell = new PdfPCell(new Phrase("",
					this.tableContentFont));
			detailBlankCell.setColspan(5);
			for (Order order : this.orderList) {
				i++;
				pdfTable.addCell(new Phrase(i.toString(), this.tableContentFont));
				pdfTable.addCell(new Phrase(order.getNumber(),
						this.tableContentFont));
				pdfTable.addCell(new Phrase(order.getCustomer().getLastName()
						+ " " + order.getCustomer().getFirstName(),
						this.tableContentFont));
				pdfTable.addCell(new Phrase(order.getCustomer().getAddress(),
						this.tableContentFont));
				pdfTable.addCell(new Phrase(order.getCustomer().getTelephone(),
						this.tableContentFont));
				pdfTable.addCell(new Phrase("Number", this.tableHeaderFont));
				pdfTable.addCell(new Phrase("Name", this.tableHeaderFont));
				pdfTable.addCell(new Phrase("Confirmed Qty.",
						this.tableHeaderFont));
				detailBlankCell.setRowspan(order.getOrderDetails().size());
				pdfTable.addCell(detailBlankCell);
				for (OrderDetail detail : order.getOrderDetails()) {
					pdfTable.addCell(new Phrase(
							detail.getProduct().getNumber(),
							this.tableContentFont));
					pdfTable.addCell(new Phrase(detail.getProduct()
							.getNameLabel(), this.tableContentFont));
					pdfTable.addCell(new Phrase(detail.getDeliveredQuantity()
							+ detail.getProduct().getPriceUnitLabel(),
							this.tableContentFont));
				}
			}
			float[] columnsWidths = { 20f, 55f, 80f, 125f, 60f, 30f, 90f, 60f };
			pdfTable.setWidths(columnsWidths);
			document.add(pdfTable);
			document.close();
			InputStream input = new ByteArrayInputStream(
					outputStream.toByteArray());
			StreamedContent content;
			content = new DefaultStreamedContent(input, "pdf",
					"OrderDetailList.pdf");
			return content;
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			this.cleanUp();
		}
		return null;
	}

	private List<Location> ordersByLocation;

	public List<Location> getOrdersByLocation() {
		return ordersByLocation;
	}

	public void setOrdersByLocation(List<Location> ordersByLocation) {
		this.ordersByLocation = ordersByLocation;
	}

	/**
	 * Prepare and deliver
	 * 
	 * @return
	 */

	public StreamedContent getOrdersByLocationLocationListPdf() {
		try {
			this.init();
			PdfPTable pdfTable = new PdfPTable(7);
			pdfTable.setWidthPercentage(100f);
			pdfTable.addCell(new Phrase("Prepare/Deliver No.",
					this.tableHeaderFont));
			pdfTable.addCell(new Phrase("Number", this.tableHeaderFont));
			pdfTable.addCell(new Phrase("Name", this.tableHeaderFont));
			pdfTable.addCell(new Phrase("Address", this.tableHeaderFont));
			pdfTable.addCell(new Phrase("Post Code", this.tableHeaderFont));
			pdfTable.addCell(new Phrase("District", this.tableHeaderFont));
			pdfTable.addCell(new Phrase("Telephone", this.tableHeaderFont));
			pdfTable.setHeaderRows(1);
			for (Location location : this.ordersByLocation) {
				pdfTable.addCell(new Phrase("  ", this.tableContentFont));
				pdfTable.addCell(new Phrase(location.getNumber(),
						this.tableContentFont));
				pdfTable.addCell(new Phrase(location.getName(),
						this.tableContentFont));
				pdfTable.addCell(new Phrase(location.getAddress(),
						this.tableContentFont));
				pdfTable.addCell(new Phrase(location.getPostCode(),
						this.tableContentFont));
				pdfTable.addCell(new Phrase(location.getDistrict(),
						this.tableContentFont));
				pdfTable.addCell(new Phrase(location.getTelephone(),
						this.tableContentFont));
			}
			float[] columnsWidths = { 40f, 60f, 80f, 150f, 80f, 50f, 60f };
			pdfTable.setWidths(columnsWidths);
			document.add(pdfTable);
			document.close();
			InputStream input = new ByteArrayInputStream(
					outputStream.toByteArray());
			StreamedContent content;
			content = new DefaultStreamedContent(input, "pdf",
					"Location(haveOrder)List.pdf");
			return content;
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			this.cleanUp();
		}
		return null;
	}

	/**
	 * Prepare and deliver
	 * 
	 * @return
	 */

	public StreamedContent getOrdersByLocationPdf() {
		try {
			this.init();
			for (Location location : this.ordersByLocation) {
				this.reportHeaderFooter.setLeftHeader(location.getNumber()
						+ " " + location.getAddress());
				pdfWriter.setPageEvent(this.reportHeaderFooter);
				this.document.newPage();
				PdfPTable pdfTable = new PdfPTable(6);
				pdfTable.setWidthPercentage(100f);
				pdfTable.addCell(new Phrase("No.", this.tableHeaderFont));
				pdfTable.addCell(new Phrase("Order No.", this.tableHeaderFont));
				pdfTable.addCell(new Phrase("Name", this.tableHeaderFont));
				pdfTable.addCell(new Phrase("Address", this.tableHeaderFont));
				pdfTable.addCell(new Phrase("Telephone", this.tableHeaderFont));
				pdfTable.addCell(new Phrase("Charge", this.tableHeaderFont));
				PdfPCell totalCell = new PdfPCell(new Phrase("Total",
						this.tableHeaderFont));
				totalCell.setColspan(5);
				pdfTable.addCell(totalCell);
				DecimalFormat df = new DecimalFormat("#.00");
				Double total = 0D;
				for (Order order : location.getOrders()) {
					total = total + order.getConfirmedTotalCharge();
				}

				pdfTable.addCell(new Phrase(df.format(total),
						this.tableHeaderFont));
				pdfTable.setHeaderRows(2);
				pdfTable.setFooterRows(1);
				Integer i = 0;
				for (Order order : location.getOrders()) {
					i++;
					pdfTable.addCell(new Phrase(i.toString(),
							this.tableContentFont));
					pdfTable.addCell(new Phrase(order.getNumber(),
							this.tableContentFont));
					pdfTable.addCell(new Phrase(order.getCustomer()
							.getLastName()
							+ " "
							+ order.getCustomer().getFirstName(),
							this.tableContentFont));
					pdfTable.addCell(new Phrase(order.getCustomer()
							.getAddress(), this.tableContentFont));
					pdfTable.addCell(new Phrase(order.getCustomer()
							.getTelephone(), this.tableContentFont));
					pdfTable.addCell(new Phrase(order
							.getConfirmedTotalChargeLabel(),
							this.tableContentFont));

				}
				float[] columnsWidths = { 40f, 80f, 100f, 150f, 100f, 50f };
				pdfTable.setWidths(columnsWidths);
				document.add(pdfTable);
			}
			document.close();
			InputStream input = new ByteArrayInputStream(
					outputStream.toByteArray());
			StreamedContent content;
			content = new DefaultStreamedContent(input, "pdf",
					"DeliveryList.pdf");
			return content;
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			this.cleanUp();
		}
		return null;
	}

	/**
	 * Prepare and deliver
	 * 
	 * @return
	 */

	public StreamedContent getOrdersByLocationWithDetailPdf() {
		try {
			this.init();
			for (Location location : this.ordersByLocation) {
				this.reportHeaderFooter.setLeftHeader(location.getNumber()
						+ ":" + location.getAddress());
				pdfWriter.setPageEvent(this.reportHeaderFooter);
				this.document.newPage();
				PdfPTable pdfTable = new PdfPTable(8);
				pdfTable.setWidthPercentage(100f);
				pdfTable.addCell(new Phrase("No.", this.tableHeaderFont));
				pdfTable.addCell(new Phrase("Order No.", this.tableHeaderFont));
				pdfTable.addCell(new Phrase("Name", this.tableHeaderFont));
				// pdfTable.addCell(new Phrase("Address",
				// this.tableHeaderFont));
				pdfTable.addCell(new Phrase("Telephone", this.tableHeaderFont));
				pdfTable.addCell(new Phrase("Charge", this.tableHeaderFont));
				PdfPCell detailTableHeaderCell = new PdfPCell(new Phrase(
						"Order Detail", this.tableHeaderFont));
				detailTableHeaderCell.setColspan(3);
				pdfTable.addCell(detailTableHeaderCell);
				pdfTable.setHeaderRows(1);
				Integer i = 0;
				for (Order order : location.getOrders()) {
					i++;
					Integer rowspan = order.getOrderDetails().size();

					PdfPCell numberCell = new PdfPCell(new Phrase(i.toString(),
							this.tableContentFont));
					numberCell.setRowspan(rowspan);
					pdfTable.addCell(numberCell);

					PdfPCell orderNumberCell = new PdfPCell(new Phrase(
							order.getNumber(), this.tableContentFont));

					orderNumberCell.setRowspan(rowspan);
					pdfTable.addCell(orderNumberCell);

					PdfPCell customerNameCell = new PdfPCell(new Phrase(order
							.getCustomer().getLastName()
							+ " "
							+ order.getCustomer().getFirstName(),
							this.tableContentFont));
					customerNameCell.setRowspan(rowspan);
					pdfTable.addCell(customerNameCell);

					// PdfPCell addressCell = new PdfPCell(new Phrase(order
					// .getCustomer().getAddress(), this.tableContentFont));
					// addressCell.setRowspan(rowspan);
					// pdfTable.addCell(addressCell);

					PdfPCell telephoneCell = new PdfPCell(new Phrase(order
							.getCustomer().getTelephone(),
							this.tableContentFont));
					telephoneCell.setRowspan(rowspan);
					pdfTable.addCell(telephoneCell);

					PdfPCell chargeCell = new PdfPCell(new Phrase(
							order.getConfirmedTotalChargeLabel(),
							this.tableContentFont));
					chargeCell.setRowspan(rowspan);
					pdfTable.addCell(chargeCell);

					for (OrderDetail detail : order.getOrderDetails()) {
						pdfTable.addCell(new Phrase(detail.getProduct()
								.getNumber(), this.tableContentFont));
						pdfTable.addCell(new Phrase(detail.getProduct()
								.getNameLabel(), this.tableContentFont));
						pdfTable.addCell(new Phrase(detail
								.getConfirmedQuantity()
								+ " "
								+ detail.getProduct().getStockUnitLabel(),
								this.tableContentFont));
					}
				}
				float[] columnsWidths = { 40f, 60f, 80f, 110f, 80f, 30f, 80f,
						40f };
				pdfTable.setWidths(columnsWidths);
				document.add(pdfTable);
			}
			document.close();
			InputStream input = new ByteArrayInputStream(
					outputStream.toByteArray());
			StreamedContent content;
			content = new DefaultStreamedContent(input, "pdf",
					"PrepareReport.pdf");
			return content;
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			this.cleanUp();
		}
		return null;
	}

	// User Activity record report

	private SalesGroupByProductQuery userRecordQuery = new SalesGroupByProductQuery();

	public SalesGroupByProductQuery getUserRecordQuery() {
		return userRecordQuery;
	}

	public void setUserRecordQuery(SalesGroupByProductQuery userRecordQuery) {
		this.userRecordQuery = userRecordQuery;
	}

	private List<UserRecord> userRecords = new ArrayList<UserRecord>();

	public List<UserRecord> getUserRecords() {
		return userRecords;
	}

	public void setUserRecords(List<UserRecord> userRecords) {
		this.userRecords = userRecords;
	}

	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public boolean equals(Object o) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean equalsId(Object o) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public int hashCode() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public void setId(Long id) {
		// TODO Auto-generated method stub

	}

	@Override
	public Long getId() {
		// TODO Auto-generated method stub
		return null;
	}

}
